package com.xin.di.uav.common.utils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.*;

/**
 * @Auther: 01404421
 * @Date: 2023/3/27 23:00
 * @Description:
 */
@Component
public class SfOssClientUtil {

    @Value("${sf.oss.user.name: sit-IE-UOCS-CORE}")
    private String userName;
    @Value("${sf.oss.account: sit-IE-UOCS-CORE}")
    private String account;
    @Value("${sf.oss.user.key: 8cf9869494e1f44ed88d5867aa573486}")
    private String userKey;
    @Value("${sf.oss.ak: c2l0LUlFLVVPQ1MtQ09SRTpzaXQtSUUtVU9DUy1DT1JF}")
    private String ak;
    @Value("${sf.oss.server.url: sit-ie-uocs-core-shenzhen-xili1-oss.sit.sf-express.com:8080}")
    private String serverUrl;
    @Value("${sf.oss.app.bucket:sfosspublic001}")
    private String bucket;


    private static Logger log = LoggerFactory.getLogger(SfOssClientUtil.class);

    private static volatile SfOssClientUtil instance;


    private volatile String v1Token = null;

    private volatile Long expireTime = null;

    private SfOssClientUtil(Environment env) {
//        userName = env.getProperty("sf.oss.user.name");
//        account = env.getProperty("sf.oss.account");
//        userKey = env.getProperty("sf.oss.user.key");
//        ak = env.getProperty("sf.oss.ak");
//        serverUrl = env.getProperty("sf.oss.server.url");
//        bucket = env.getProperty("sf.oss.default.bucket");
    }

    public static SfOssClientUtil getInstance(Environment env) {
        if (ObjectUtils.isEmpty(instance)) {
            synchronized (SfOssClientUtil.class) {
                instance = new SfOssClientUtil(env);
            }
        }
        return instance;
    }

    /**
     * 桶之间的复制,因此生成的token要适配2个桶
     *
     * @return
     * @
     */
    public String getV1Token()  {
        String token = null;
        try {
            HttpGet get = new HttpGet("http://" + this.serverUrl + "/auth/v1.0");
            get.setHeader("X-Auth-User", ak);
            get.setHeader("X-Auth-Key", userKey);
            CloseableHttpClient httpclient = HttpClients.createDefault();
            CloseableHttpResponse response = httpclient.execute(get);
            // 判断返回状态是否为200
            int statusCode = response.getStatusLine().getStatusCode();
            if (200 == statusCode) {
                if (response.getFirstHeader("X-Auth-Token") != null) {
                    token = response.getFirstHeader("X-Auth-Token").getValue();
                    setV1TokenExpires(response.getFirstHeader("X-Auth-Token-Expires").getValue());
                }
            } else {
            }
        } catch (Exception e) {
        }
        return token;
    }

    public void setV1TokenExpires(String s) {
        this.expireTime = new Date().getTime() / 1000 + Long.valueOf(s);
    }


    private String setV1Token()  {
        if (null == v1Token) {
            v1Token = getV1Token();
        } else if (new Date().getTime() / 1000 >= expireTime) {
            v1Token = getV1Token();
        }
        return v1Token;
    }

    public void uploadV1(String bucket, String fileName, InputStream is)  {
        String url = new StringBuilder("http://" + serverUrl)
                .append("/v1")
                .append("/AUTH_").append(account)
                .append("/").append(bucket)
                .append("/").append(fileName).toString();
        Header[] headers = new Header[]{
                new BasicHeader("account", account),
                new BasicHeader("container", bucket),
                new BasicHeader("X-Auth-Token", setV1Token())
        };
        log.info("uploadV1 url:{}, headers:{}", url, JSON.toJSONString(headers));
        Map<String, Object> ret = sendPutWithFileAndReturnMap(url, headers, is);
        log.info("uploadV1 response: {}", JSON.toJSONString(ret));
    }

    public void uploadV1(String fileName, InputStream is)  {
        uploadV1(bucket, fileName, is);
    }

    public void uploadV1WithDlo(String bucket, String fileName)  {
        String url = new StringBuilder("http://" + serverUrl)
                .append("/v1")
                .append("/AUTH_").append(account)
                .append("/").append(bucket)
                .append("/").append(fileName).toString();

        Header[] headers = new Header[]{
                new BasicHeader("account", account),
                new BasicHeader("container", bucket),
                new BasicHeader("X-Auth-Token", setV1Token()),
                new BasicHeader("object", fileName),
                new BasicHeader("X-Object-Manifest", bucket + "/" + fileName)
        };
        log.info("uploadV1WithDlo url:{}, headers:{}", url, JSON.toJSONString(headers));
        int r = sendPutOnlyHeader(url, headers);
        log.info("uploadV1WithDlo response: {}", r);
    }

    public void uploadV1WithDlo(String fileName)  {
        uploadV1WithDlo(bucket, fileName);
    }

    private static Map<String, Object> sendPutWithFileAndReturnMap(String url, Header[] headers, InputStream inputStream) {
        // 创建Httpclient对象
        Map<String, Object> ret = new HashMap<>();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            // 创建Http Post请求
            HttpPut httpPut = new HttpPut(url);
            HttpEntity entity = new InputStreamEntity(inputStream);
            httpPut.setEntity(entity);
            if (null != headers && headers.length > 0) {
                httpPut.setHeaders(headers);
            }
            response = httpClient.execute(httpPut);
            ret.put("status", response.getStatusLine().getStatusCode());
            ret.put("headers", response.getAllHeaders());
            return ret;
        } catch (Exception e) {
            log.error("sendPutWithFileAndReturnMap error", e);
        } finally {
            try {
                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("sendPutWithFileAndReturnMap error", e);
            }
        }
        ret.put("status", 400);
        return ret;
    }

    private static int sendPutOnlyHeader(String url, Header[] headers) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            // 创建Http Post请求
            HttpPut httpPut = new HttpPut(url);
            if (null != headers && headers.length > 0) {
                httpPut.setHeaders(headers);
            }
            response = httpClient.execute(httpPut);
            return response.getStatusLine().getStatusCode();
        } catch (Exception e) {
            log.error("sendPutOnlyHeader error", e);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("sendPutOnlyHeader error", e);
            }
        }
        return 400;
    }

}
